home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / What's New? / Development Kits / Mac OS / USB DDK 1.4.6f4 / Examples / PrinterClassDriver / PrintChooserSample / SafeNameRegistry.cp < prev    next >
Encoding:
Text File  |  2000-09-25  |  21.6 KB  |  683 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        SafeNameRegistry.cp
  3.  
  4.     Contains:    Stub routines for name registry calls
  5.  
  6.     Think of the Name Registry as a database used by System software 
  7.     to keep track of hardware and other settings. Its up to the 
  8.     indivdual software (called expert software) to insert and remove 
  9.     entries from the Name Registry. The information contained inside 
  10.     the entries can be whatever the expert software deems important.
  11.  
  12.     The Name Registry is only available on PCI based Macs. The Name
  13.     Registry routines reside in a PPC shared library (there isn't a
  14.     68K version), hence the need for these stub routines. When we build
  15.     fat drivers there is a chance on a PPC of running the 68K version
  16.     of the driver. Therefore we needed a way of calling into the Name
  17.     Registry shared library from 68K code. These routines will load the
  18.     Name Registry library and create procptrs for the needed calls. The
  19.     same stub calls will work on PPC and 68K
  20.  
  21.  
  22.  
  23.     Copyright:    © 1998, 2000 by Apple Computer, Inc., all rights reserved.
  24.  
  25.     Writers:
  26.  
  27.         (gc)    Garth Cummings
  28.  
  29.     Change History (most recent first):
  30.  
  31.       <USB1>     5/11/00    gc        first checked in
  32.         10 Jun 98    gp        Use a local variable to store the name registry routine address
  33.                             before assigning it to our global area
  34.         9  Jun 98     gp        Use our connection id when looking for routine addresses
  35.                             Use DisposeRoutineDescriptorTrap when disposing of the
  36.         4  May 98     gp        Replaced Find_Symbol with FindAddress
  37.         25 Mar 98     gp        Added calls to create and remove name registry proc ptrs
  38.         18 Mar 98     gp        Created
  39.  
  40.     To Do:
  41. */
  42.  
  43. #ifndef __Chooser__
  44. #include "Chooser.h"
  45. #endif
  46.  
  47. #ifndef __CODEFRAGMENTS__
  48. #include <CodeFragments.h>
  49. #endif
  50.  
  51. #ifndef __MIXEDMODE__
  52. #include <MixedMode.h>
  53. #endif
  54.  
  55. #ifndef __GESTALT__
  56. #include <Gestalt.h>
  57. #endif
  58.  
  59. #ifndef __ERRORS__
  60. #include <Errors.h>
  61. #endif
  62.  
  63. #ifndef __DIALOGS__
  64. #include <Dialogs.h>
  65. #endif
  66.  
  67. #ifndef __SafeNameRegistry__
  68. #include "SafeNameRegistry.h"
  69. #endif
  70.  
  71. /******************************************************************************
  72.     Prototypes
  73.  ******************************************************************************/
  74.  
  75. // prototypes used to find address of routine in name registry library
  76. OSErr FindAddress(Ptr* pSymAddr, Str255 pSymName, ProcInfoType pProcInfo);
  77. pascal OSErr GetSystemArchitecture(OSType *archType);
  78.  
  79. /******************************************************************************
  80.     Typedefs
  81.  ******************************************************************************/
  82.  
  83. // proc typedefs for calling routines in the name registry library
  84. typedef pascal OSStatus (*RegistryEntryIDInitProcPtr) ( RegEntryID* id );
  85. typedef pascal OSStatus (*RegistryCStrEntryLookupProcPtr) ( RegEntryID* searchPointID, 
  86.             RegCStrPathName* pathName, RegEntryID*foundEntry );
  87. typedef pascal OSStatus (*RegistryEntryIterateCreateProcPtr) ( RegEntryIter* cookie );
  88. typedef pascal OSStatus (*RegistryEntryIterateDisposeProcPtr) ( RegEntryIter* cookie );
  89. typedef pascal OSStatus (*RegistryEntryIterateSetProcPtr) ( RegEntryIter* cookie, RegEntryID *startEntryID );
  90. typedef pascal OSStatus (*RegistryEntryIterateProcPtr) ( RegEntryIter *cookie, 
  91.             RegEntryIterationOp relationship, RegEntryID *foundEntry, Boolean *done );
  92. typedef pascal OSStatus (*RegistryEntryIDDisposeProcPtr) ( RegEntryID* id );
  93. typedef pascal OSStatus (*RegistryPropertyGetProcPtr) ( RegEntryID *entryID, 
  94.             RegPropertyName *propertyName, void *propertyValue, RegPropertyValueSize *propertySize );
  95.  
  96. /******************************************************************************
  97.     Constants
  98.  ******************************************************************************/
  99.  
  100. #define    kNoNameRegistryAlert        3000
  101.  
  102. // stack descriptors used in the name registry stub calls to pass params
  103. // to the proper routine in the name registry shared library
  104.  
  105. enum {
  106.     kRegistryEntryIDInitProcInfo = kPascalStackBased
  107.     | RESULT_SIZE( SIZE_CODE(sizeof(OSStatus)))
  108.     | STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryID*)))
  109. };
  110. enum {
  111.     kRegistryCStrEntryLookupProcInfo = kPascalStackBased
  112.     | RESULT_SIZE( SIZE_CODE(sizeof(OSStatus)))
  113.     | STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryID*)))
  114.     | STACK_ROUTINE_PARAMETER( 2, SIZE_CODE(sizeof( RegCStrPathName*)))
  115.     | STACK_ROUTINE_PARAMETER( 3, SIZE_CODE(sizeof( RegEntryID*)))
  116. };
  117. enum {
  118.     kRegistryEntryIterateCreateProcInfo = kPascalStackBased
  119.     | RESULT_SIZE( SIZE_CODE(sizeof(OSStatus)))
  120.     | STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryIter*)))
  121. };
  122. enum {
  123.     kRegistryEntryIterateDisposeProcInfo = kPascalStackBased
  124.     | RESULT_SIZE( SIZE_CODE(sizeof(OSStatus)))
  125.     | STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryIter*)))
  126. };
  127. enum {
  128.     kRegistryEntryIterateSetProcInfo = kPascalStackBased
  129.     | RESULT_SIZE( SIZE_CODE(sizeof(OSStatus)))
  130.     | STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryIter*)))
  131.     | STACK_ROUTINE_PARAMETER( 2, SIZE_CODE(sizeof( RegEntryID*)))
  132. };
  133. enum {
  134.     kRegistryEntryIterateProcInfo = kPascalStackBased
  135.     | RESULT_SIZE( SIZE_CODE(sizeof(OSStatus)))
  136.     | STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryIter*)))
  137.     | STACK_ROUTINE_PARAMETER( 2, SIZE_CODE(sizeof( RegEntryIterationOp)))
  138.     | STACK_ROUTINE_PARAMETER( 3, SIZE_CODE(sizeof( RegEntryID*)))
  139.     | STACK_ROUTINE_PARAMETER( 4, SIZE_CODE(sizeof( Boolean*)))
  140. };
  141. enum {
  142.     kRegistryEntryIDDisposeProcInfo = kPascalStackBased
  143.     | RESULT_SIZE( SIZE_CODE(sizeof(OSStatus)))
  144.     | STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryID*)))
  145. };
  146. enum {
  147.     kRegistryPropertyGetProcInfo = kPascalStackBased
  148.     | RESULT_SIZE( SIZE_CODE(sizeof(OSStatus)))
  149.     | STACK_ROUTINE_PARAMETER( 1, SIZE_CODE(sizeof( RegEntryID*)))
  150.     | STACK_ROUTINE_PARAMETER( 2, SIZE_CODE(sizeof( RegPropertyName*)))
  151.     | STACK_ROUTINE_PARAMETER( 3, SIZE_CODE(sizeof( void*)))
  152.     | STACK_ROUTINE_PARAMETER( 4, SIZE_CODE(sizeof( RegPropertyValueSize*)))
  153. };
  154.  
  155. /*-----------------------------------------------------------------------------*
  156.  
  157.     NameRegistryInstalled
  158.     
  159.     Desc:        Test to see if the name registry exists on this machine
  160.  
  161.     In:            None
  162.  
  163.     Out:        True if name registry exists else false
  164.     
  165.     History:
  166.  
  167.     18 Mar 98    gp        Added.
  168.     
  169. *-----------------------------------------------------------------------------*/
  170. Boolean    NameRegistryInstalled( void )
  171. {
  172.     OSErr    err=noErr;        // result from gestalt call
  173.     long    result;
  174.     USBGlobalsHandle    gGlobals=nil;        // our global data area
  175.  
  176.     gGlobals = GetGlobalStorage();
  177.  
  178.     // if not our first time then return previous result
  179.     if( (**gGlobals).checkedForNameRegistry == true )
  180.         return (**gGlobals).hasNameRegistry;
  181.     else {
  182.  
  183.     // check to see if name registry exists
  184.         err = Gestalt(gestaltNameRegistryVersion, &result);
  185.         if( err == noErr )
  186.             (**gGlobals).hasNameRegistry = true;
  187.         else {
  188.             (**gGlobals).hasNameRegistry = false;
  189.     // put up alert if it isn't installed
  190.             StopAlert(kNoNameRegistryAlert, nil);
  191.         }
  192.         (**gGlobals).checkedForNameRegistry=true;
  193.     }
  194.     return (**gGlobals).hasNameRegistry;
  195. }
  196.  
  197. /*-----------------------------------------------------------------------------*
  198.  
  199.     SafeRegistryEntryIDInit
  200.     
  201.     Desc:        Stub code for name registry routine 'RegistryEntryIDInit'
  202.  
  203.     In:            id - pointer to a RegEntryID to initialize
  204.  
  205.     Out:        returns any errors which may have occur
  206.     
  207.     History:
  208.  
  209.     18 Mar 98    gp        Added.
  210.     
  211. *-----------------------------------------------------------------------------*/
  212.  
  213. OSStatus SafeRegistryEntryIDInit(RegEntryID *id)
  214. {
  215.     OSStatus    anErr=-1;                // return value
  216.     USBGlobalsHandle    gGlobals=nil;    // our global data area
  217.  
  218.     gGlobals = GetGlobalStorage();
  219.  
  220.     if( gGlobals != nil && (Ptr) (**gGlobals).RegistryEntryIDInitAddr != (Ptr) nil )
  221.         anErr = ((RegistryEntryIDInitProcPtr) (**gGlobals).RegistryEntryIDInitAddr) (id);
  222.     return anErr;
  223. }
  224.  
  225. /*-----------------------------------------------------------------------------*
  226.  
  227.     SafeRegistryCStrEntryLookup
  228.     
  229.     Desc:        Stub code for name registry routine 'RegistryCStrEntryLookup'
  230.  
  231.     In:            searchPointID - the RegEntryID to start searching from
  232.                 pathName - the cstring path of the entry to find
  233.                 foundEntry - where to store the found entry
  234.  
  235.     Out:        foundEntry - the RegEntryID of any found entry
  236.                 returns any errors which may have occur
  237.     
  238.     History:
  239.  
  240.     18 Mar 98    gp        Added.
  241.     
  242. *-----------------------------------------------------------------------------*/
  243. OSStatus SafeRegistryCStrEntryLookup( RegEntryID *searchPointID, RegCStrPathName *pathName, RegEntryID *foundEntry)
  244. {
  245.     OSStatus    anErr=-1;                // return value
  246.     USBGlobalsHandle    gGlobals=nil;    // our global data area
  247.  
  248.     gGlobals = GetGlobalStorage();
  249.     
  250.     // now call it
  251.     if( gGlobals != nil && (Ptr) (**gGlobals).RegistryCStrEntryLookupAddr != (Ptr) nil )
  252.         anErr = ((RegistryCStrEntryLookupProcPtr) (**gGlobals).RegistryCStrEntryLookupAddr) (searchPointID, pathName, foundEntry);
  253.     return anErr;
  254. }
  255.  
  256. /*-----------------------------------------------------------------------------*
  257.  
  258.     SafeRegistryEntryIterateCreate
  259.     
  260.     Desc:        Stub code for name registry routine 'RegistryEntryIterateCreate'
  261.  
  262.     In:            id - pointer to a RegEntryIter to initialize
  263.  
  264.     Out:        returns any errors which may have occur
  265.     
  266.     History:
  267.  
  268.     18 Mar 98    gp        Added.
  269.     
  270. *-----------------------------------------------------------------------------*/
  271. OSStatus SafeRegistryEntryIterateCreate(RegEntryIter *cookie)
  272. {
  273.     OSStatus    anErr=-1;                // return value
  274.     USBGlobalsHandle    gGlobals=nil;    // our global data area
  275.  
  276.     gGlobals = GetGlobalStorage();
  277.  
  278.     if( gGlobals != nil && (Ptr) (**gGlobals).RegistryEntryIterateCreateAddr != (Ptr) nil )
  279.         anErr = ((RegistryEntryIterateCreateProcPtr) (**gGlobals).RegistryEntryIterateCreateAddr) (cookie);
  280.     return anErr;
  281. }
  282.  
  283. /*-----------------------------------------------------------------------------*
  284.  
  285.     SafeRegistryEntryIterateDispose
  286.     
  287.     Desc:        Stub code for name registry routine 'RegistryEntryIterateDispose'
  288.  
  289.     In:            cookie - iterator to dispose
  290.  
  291.     Out:        returns any errors which may have occur
  292.     
  293.     History:
  294.  
  295.     18 Mar 98    gp        Added.
  296.     
  297. *-----------------------------------------------------------------------------*/
  298. OSStatus SafeRegistryEntryIterateDispose(RegEntryIter *cookie)
  299. {
  300.     OSStatus    anErr=-1;                // return value
  301.     USBGlobalsHandle    gGlobals=nil;    // our global data area
  302.  
  303.     gGlobals = GetGlobalStorage();
  304.  
  305.     if( gGlobals != nil && (Ptr) (**gGlobals).RegistryEntryIterateDisposeAddr != (Ptr) nil )
  306.         anErr = ((RegistryEntryIterateDisposeProcPtr) (**gGlobals).RegistryEntryIterateDisposeAddr) (cookie);
  307.     return anErr;
  308. }
  309.  
  310. /*-----------------------------------------------------------------------------*
  311.  
  312.     SafeRegistryEntryIterateSet
  313.     
  314.     Desc:        Stub code for name registry routine 'RegistryEntryIterateSet'
  315.  
  316.     In:            cookie - pointer to iterator to set
  317.                 startEntryID - name registry entry to start iterating from
  318.  
  319.     Out:        returns any errors which may have occur
  320.     
  321.     History:
  322.  
  323.     18 Mar 98    gp        Added.
  324.     
  325. *-----------------------------------------------------------------------------*/
  326. OSStatus SafeRegistryEntryIterateSet(RegEntryIter *cookie, RegEntryID *startEntryID)
  327. {
  328.     OSStatus    anErr=-1;                // return value
  329.     USBGlobalsHandle    gGlobals=nil;    // our global data area
  330.  
  331.     gGlobals = GetGlobalStorage();
  332.  
  333.     if( gGlobals != nil && (Ptr) (**gGlobals).RegistryEntryIterateSetAddr != (Ptr) nil )
  334.         anErr = ((RegistryEntryIterateSetProcPtr) (**gGlobals).RegistryEntryIterateSetAddr) (cookie, startEntryID);
  335.     return anErr;
  336. }
  337.  
  338. /*-----------------------------------------------------------------------------*
  339.  
  340.     SafeRegistryEntryIterate
  341.     
  342.     Desc:        Stub code for name registry routine 'RegistryEntryIterate'
  343.  
  344.     In:            cookie - iterator to use
  345.                 relationship - direction to iterate
  346.                 foundEntry - where to store next name entry found
  347.                 done - tells if we're done with iteration
  348.  
  349.     Out:        foundEntry - RegEntryID of name entry found
  350.                 done - true if no more entries found
  351.                 returns any errors which may have occur
  352.     
  353.     History:
  354.  
  355.     18 Mar 98    gp        Added.
  356.     
  357. *-----------------------------------------------------------------------------*/
  358. OSStatus SafeRegistryEntryIterate(RegEntryIter *cookie, RegEntryIterationOp relationship, 
  359.         RegEntryID *foundEntry, Boolean *done)
  360. {
  361.     OSStatus    anErr=-1;                // return value
  362.     USBGlobalsHandle    gGlobals=nil;    // our global data area
  363.  
  364.     gGlobals = GetGlobalStorage();
  365.  
  366.     if( gGlobals != nil && (Ptr) (**gGlobals).RegistryEntryIterateAddr != (Ptr) nil )
  367.         anErr = ((RegistryEntryIterateProcPtr) (**gGlobals).RegistryEntryIterateAddr) (cookie, relationship, foundEntry, done);
  368.     return anErr;
  369. }
  370.  
  371. /*-----------------------------------------------------------------------------*
  372.  
  373.     SafeRegistryEntryIDDispose
  374.     
  375.     Desc:        Stub code for name registry routine 'RegistryEntryIDDispose'
  376.  
  377.     In:            id - RegEntryID to dispose
  378.  
  379.     Out:        returns any errors which may have occur
  380.     
  381.     History:
  382.  
  383.     18 Mar 98    gp        Added.
  384.     
  385. *-----------------------------------------------------------------------------*/
  386. OSStatus SafeRegistryEntryIDDispose(RegEntryID *id)
  387. {
  388.     OSStatus    anErr=-1;                // return value
  389.     USBGlobalsHandle    gGlobals=nil;    // our global data area
  390.  
  391.     gGlobals = GetGlobalStorage();
  392.  
  393.     if( gGlobals != nil && (Ptr) (**gGlobals).RegistryEntryIDDisposeAddr != (Ptr) nil )
  394.         anErr = ((RegistryEntryIDDisposeProcPtr) (**gGlobals).RegistryEntryIDDisposeAddr) (id);
  395.     return anErr;
  396. }
  397.  
  398. /*-----------------------------------------------------------------------------*
  399.  
  400.     SafeRegistryPropertyGet
  401.     
  402.     Desc:        Stub code for name registry routine 'RegistryPropertyGet'
  403.  
  404.     In:            entryID - RegEntryID value that identifies a name entry
  405.                 propertyName - name of the property
  406.                 propertyValue - buffer to hold the property
  407.                 propertySize - size of the property buffer
  408.  
  409.     Out:        propertySize - size of the property retrieved
  410.                 returns any errors which may have occur
  411.     
  412.     History:
  413.  
  414.     18 Mar 98    gp        Added.
  415.     
  416. *-----------------------------------------------------------------------------*/
  417. OSStatus SafeRegistryPropertyGet( RegEntryID *entryID, RegPropertyName *propertyName, 
  418.         void *propertyValue, RegPropertyValueSize *propertySize)
  419. {
  420.     OSStatus    anErr=-1;                // return value
  421.     USBGlobalsHandle    gGlobals=nil;    // our global data area
  422.  
  423.     gGlobals = GetGlobalStorage();
  424.  
  425.     if( gGlobals != nil && (Ptr) (**gGlobals).RegistryPropertyGetAddr != (Ptr) nil )
  426.         anErr = ((RegistryPropertyGetProcPtr) (**gGlobals).RegistryPropertyGetAddr) (entryID, propertyName, propertyValue, propertySize);
  427.     return anErr;
  428. }
  429.  
  430. /*-----------------------------------------------------------------------------*
  431.  
  432.     GetSystemArchitecture
  433.     
  434.     Desc:        Taken from 
  435.                 DTS Technote 1077 "Calling CFM Code from Classic 68K Code".
  436.                 Returns architect of current cpu during runtime.
  437.  
  438.  
  439.     In:            archType - address of variable to hold architect type
  440.  
  441.     Out:        archType - returns architect of current cpu pointed by this variable
  442.                 Also returns any errors
  443.     
  444.     History:
  445.  
  446.     18 Mar 98    gp        Added.
  447.     
  448. *-----------------------------------------------------------------------------*/
  449.  
  450. pascal OSErr GetSystemArchitecture(OSType *archType)
  451. {
  452.     long sSysArchitecture = 0; // static so we only Gestalt once.
  453.     OSErr tOSErr = noErr;
  454.     
  455.     *archType = kAnyCFragArch;   // assume wild architecture
  456.     
  457.     // If we don't know the system architecture yet...
  458.     if (sSysArchitecture == 0)
  459.         // ...Ask Gestalt what kind of machine we are running on.
  460.         tOSErr = Gestalt(gestaltSysArchitecture, &sSysArchitecture);
  461.     
  462.     if (tOSErr == noErr) // if no errors
  463.     {
  464.         if (sSysArchitecture == gestalt68k)   // 68k?
  465.              *archType = kMotorola68KCFragArch;   
  466.         else if (sSysArchitecture == gestaltPowerPC) // PPC?
  467.              *archType = kPowerPCCFragArch;       
  468.         else
  469.              tOSErr = gestaltUnknownErr;  // who knows what might be next?
  470.     }
  471.     return tOSErr;
  472. }
  473.  
  474. /*-----------------------------------------------------------------------------*
  475.  
  476.     FindAddress
  477.     
  478.     Desc:        Taken from 
  479.                 DTS Technote 1077 "Calling CFM Code from Classic 68K Code".
  480.                 Returns the address of a routine in a shared library
  481.  
  482.     In:            pSymAddr - address of variable to hold returned address
  483.                 pSymName - a pstring of the name of the routine
  484.                 pProcInfo - stack descriptor for the routine
  485.  
  486.     Out:        pSymAddr - the address of the routine pointed by this variable
  487.                 Also returns any errors
  488.     
  489.     History:
  490.  
  491.     10 Jun 98    gp        Init the address ptr passed in before using it
  492.     9  Jun 98    gp        Use our connection id to the name registry instead of
  493.                         opening it every time
  494.     18 Mar 98    gp        Added.
  495.     
  496. *-----------------------------------------------------------------------------*/
  497.  
  498. OSErr FindAddress(Ptr* pSymAddr, Str255 pSymName, ProcInfoType pProcInfo)
  499. {
  500.     CFragConnectionID sCID = 0;
  501.     OSType sArchType = kAnyCFragArch;
  502.     OSErr sOSErr = noErr;
  503.     USBGlobalsHandle    gGlobals=nil;        // our global data area
  504.  
  505.     Str255 errMessage;
  506.     Ptr mainAddr;
  507.     CFragSymbolClass symClass;
  508.           ISAType tISAType;
  509.     
  510.     *pSymAddr = (Ptr) kUnresolvedCFragSymbolAddress;
  511.  
  512.     if( NameRegistryInstalled() == false )
  513.         return -1;            // return general error - gp
  514.     
  515.     gGlobals = GetGlobalStorage();
  516.  
  517.     if (sArchType == kAnyCFragArch)  // if architecture is undefined...
  518.     {
  519.         sCID = 0;     // ...force (re)connect to library
  520.         sOSErr = GetSystemArchitecture(&sArchType); // determine architecture
  521.         if (sOSErr != noErr)
  522.              return sOSErr; // OOPS!
  523.     }
  524.     
  525.     if (sArchType == kMotorola68KCFragArch) // ...for CFM68K
  526.           tISAType = kM68kISA | kCFM68kRTA;
  527.     else if (sArchType == kPowerPCCFragArch)  // ...for PPC CFM
  528.           tISAType = kPowerPCISA | kPowerPCRTA;
  529.     else
  530.         sOSErr = gestaltUnknownErr; // who knows what might be next?
  531.     
  532.      sCID = (**gGlobals).sCID;
  533.     if (sCID == 0) // If we haven't connected to the library yet...
  534.     {
  535.         // NOTE: The library name is hard coded here.
  536.         // I try to isolate the glue code, one file per library.
  537.         // I have had developers pass in the Library name to allow
  538.         // plug-in type support. Additional code has to be added to
  539.         // each entry points glue routine to support multiple or
  540.         // switching connection IDs.
  541.         sOSErr = GetSharedLibrary("\pNameRegistryLib", sArchType, kLoadCFrag,
  542.                    &sCID, &mainAddr, errMessage);
  543.         if (sOSErr != noErr)
  544.              return sOSErr; // OOPS!
  545.          (**gGlobals).sCID = sCID;            // save connection id
  546.     }
  547.     
  548.     // If we haven't looked up this symbol yet...
  549.     if ((Ptr) *pSymAddr == (Ptr) kUnresolvedCFragSymbolAddress)    
  550.     {
  551.         // ...look it up now
  552.         sOSErr = FindSymbol(sCID,pSymName,pSymAddr,&symClass);
  553.         if (sOSErr != noErr) {// in case of error...
  554.          // ...clear the procedure pointer
  555.              *pSymAddr = (Ptr) kUnresolvedCFragSymbolAddress;
  556.         }
  557.         #if !GENERATINGCFM // if this is classic 68k code...
  558.          *pSymAddr = (Ptr)NewRoutineDescriptorTrap((ProcPtr) *pSymAddr,
  559.                       pProcInfo, tISAType);  // ...create a routine descriptor...
  560.         #endif
  561.     }
  562.     return sOSErr;
  563. }
  564.  
  565. /*-----------------------------------------------------------------------------*
  566.  
  567.     InitNameRegistryPtrs
  568.     
  569.     Desc:        Create all the proc ptrs to Name Registry calls we will
  570.                 need
  571.  
  572.     In:            None
  573.  
  574.     Out:        None
  575.     
  576.     History:
  577.  
  578.     10 Jun 98    gp        Use a local variable to store the routine address
  579.     9  Jun 98    gp        Init our connection id to the name registry
  580.     25 Mar 98    gp        Created
  581.     
  582. *-----------------------------------------------------------------------------*/
  583. void    InitNameRegistryPtrs( void )
  584. {
  585.     USBGlobalsHandle    gGlobals = nil;        // our global data area
  586.     Ptr                    address = nil;
  587.  
  588.     gGlobals = GetGlobalStorage();
  589.  
  590.     if( gGlobals != nil && NameRegistryInstalled() == true) {
  591.         (**gGlobals).sCID = 0;
  592.  
  593.         FindAddress( (Ptr*) &address, 
  594.                 "\pRegistryEntryIDInit", kRegistryEntryIDInitProcInfo );
  595.         (**gGlobals).RegistryEntryIDInitAddr = (ProcPtr) address;
  596.  
  597.         FindAddress( (Ptr*) &address, 
  598.                 "\pRegistryCStrEntryLookup", kRegistryCStrEntryLookupProcInfo );
  599.         (**gGlobals).RegistryCStrEntryLookupAddr = (ProcPtr) address;
  600.  
  601.         FindAddress( (Ptr*) &address, 
  602.                 "\pRegistryEntryIterateCreate", kRegistryEntryIterateCreateProcInfo );
  603.         (**gGlobals).RegistryEntryIterateCreateAddr = (ProcPtr) address;
  604.  
  605.         FindAddress( (Ptr*) &address, 
  606.                 "\pRegistryEntryIterateDispose", kRegistryEntryIterateDisposeProcInfo );
  607.         (**gGlobals).RegistryEntryIterateDisposeAddr = (ProcPtr) address;
  608.  
  609.         FindAddress( (Ptr*) &address, 
  610.                 "\pRegistryEntryIterateSet", kRegistryEntryIterateSetProcInfo );
  611.         (**gGlobals).RegistryEntryIterateSetAddr = (ProcPtr) address;
  612.  
  613.         FindAddress( (Ptr*) &address, 
  614.                 "\pRegistryEntryIterate", kRegistryEntryIterateProcInfo );
  615.         (**gGlobals).RegistryEntryIterateAddr = (ProcPtr) address;
  616.  
  617.         FindAddress( (Ptr*) &address, 
  618.                 "\pRegistryEntryIDDispose", kRegistryEntryIDDisposeProcInfo );
  619.         (**gGlobals).RegistryEntryIDDisposeAddr = (ProcPtr) address;
  620.  
  621.         FindAddress( (Ptr*) &address, 
  622.                 "\pRegistryPropertyGet", kRegistryPropertyGetProcInfo );
  623.         (**gGlobals).RegistryPropertyGetAddr = (ProcPtr) address;
  624.     }
  625. }
  626.  
  627. /*-----------------------------------------------------------------------------*
  628.  
  629.     RemoveNameRegistryPtrs
  630.     
  631.     Desc:        Remove all the proc ptrs we created for Name Registry calls
  632.  
  633.     In:            None
  634.  
  635.     Out:        None
  636.     
  637.     History:
  638.  
  639.     9  Jun 98    gp        Close our connection id to the name registry
  640.                         Use DisposeRoutineDescriptorTrap when disposing of the
  641.                         name registry routine descriptors
  642.     25 Mar 98    gp        Created
  643.     
  644. *-----------------------------------------------------------------------------*/
  645. void    RemoveNameRegistryPtrs(void)
  646. {
  647.     USBGlobalsHandle    gGlobals=nil;        // our global data area
  648.     CFragConnectionID sCID;
  649.  
  650.     
  651.     gGlobals = GetGlobalStorage();
  652.     if( gGlobals != nil ) {
  653.         // dispose of proc ptrs
  654.         
  655.         if( (**gGlobals).RegistryEntryIDInitAddr != nil )
  656.             DisposeRoutineDescriptorTrap( (**gGlobals).RegistryEntryIDInitAddr);
  657.         
  658.         if( (**gGlobals).RegistryCStrEntryLookupAddr != nil )
  659.             DisposeRoutineDescriptorTrap( (**gGlobals).RegistryCStrEntryLookupAddr);
  660.         
  661.         if( (**gGlobals).RegistryEntryIterateCreateAddr != nil )
  662.             DisposeRoutineDescriptorTrap( (**gGlobals).RegistryEntryIterateCreateAddr);
  663.         
  664.         if( (**gGlobals).RegistryEntryIterateDisposeAddr != nil )
  665.             DisposeRoutineDescriptorTrap( (**gGlobals).RegistryEntryIterateDisposeAddr);
  666.         
  667.         if( (**gGlobals).RegistryEntryIterateSetAddr != nil )
  668.             DisposeRoutineDescriptorTrap( (**gGlobals).RegistryEntryIterateSetAddr);
  669.         
  670.         if( (**gGlobals).RegistryEntryIterateAddr != nil )
  671.             DisposeRoutineDescriptorTrap( (**gGlobals).RegistryEntryIterateAddr);
  672.         
  673.         if( (**gGlobals).RegistryEntryIDDisposeAddr != nil )
  674.             DisposeRoutineDescriptorTrap( (**gGlobals).RegistryEntryIDDisposeAddr);
  675.         
  676.         if( (**gGlobals).RegistryPropertyGetAddr != nil )
  677.             DisposeRoutineDescriptorTrap( (**gGlobals).RegistryPropertyGetAddr);
  678.  
  679.         sCID = (**gGlobals).sCID;
  680.         CloseConnection( &sCID );
  681.     }
  682. }
  683.